package org.example.proxy;

import org.example.reflection.PersonObj;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @version: 1
 * @description: java
 * @author: java
 * @create: 2020-06-04 21:20
 **/
public class dynamicProxy {
    public static void main(String[] args) {
        PersonProduct personProduct = new PersonProduct();
        PersonFactory instance = (PersonFactory) ProxyFactoryPerson.getProxyInstance(personProduct);
        //当通过代理类对象调用方法时，会自动的调用被代理类中同名的方法
        instance.show();
        System.out.println(instance.eat("麻辣烫"));
    }
}

interface PersonFactory {
    public void show();

    public String eat(String food);
}

//被代理类
class PersonProduct implements PersonFactory {

    @Override
    public void show() {
        System.out.println("一个人被生产了");
    }

    @Override
    public String eat(String food) {
        return "这个人喜欢吃" + food;
    }
}

//具体增强的类
class EnhanceUtil {
    public static void before() {
        System.out.println("润滑");
    }

    public static void after() {
        System.out.println("抚养");
    }
}

//代理类
class ProxyFactoryPerson {
    //调用此方法返回一个代理对象
    public static Object getProxyInstance(Object object) {//object指的被代理对象
        MyInvocationHandler handler = new MyInvocationHandler();
        handler.bind(object);
        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),
                handler);
    }
}

class MyInvocationHandler implements InvocationHandler {

    private Object obj;//需要使用被代理类的对象进行赋值

    public void bind(Object obj) {
        this.obj = obj;
    }

    //当我们通过代理类对象调用a方法时，就会自动调用如下的方法：invoke()
    //将被代理类要执行的a方法的功能就声明在invoke()方法中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        EnhanceUtil.before();
        Object returnValue = method.invoke(obj, args);
        EnhanceUtil.after();
        //上述方法的返回值就作为当前类中的invoke()的返回值。
        return returnValue;
    }
}

